"""
Polynomial chaos exploitation
=============================
"""
# %%
# In this example we are going to create a global approximation of a model response using functional chaos and expose the associated results:
#
# - the composed model: :math:`h`: :math:`\underline{Z}^{\strut} \longrightarrow \underline{Y} = g \circ T^{-1}(\underline{Z})`, which is the model of the reduced variables :math:`\underline{Z}`. We have  :math:`\displaystyle h =  \sum_{k \in \mathbb N} \underline{\alpha}_k \Psi_k`,
# - the coefficients of the polynomial approximation : :math:`(\underline{\alpha}_k)_{k \in K}`,
# - the composed meta model: :math:`\hat{h}`, which is the model of the reduced variables reduced to the truncated multivariate basis :math:`(\Psi_k)_{k \in K}`. We have :math:`\displaystyle  \hat{h} = \sum_{k \in K} \underline{\alpha}_k \Psi_k`,
# - the meta model: :math:`\displaystyle \hat{g} : \underline{X} \longrightarrow Y = \hat{h} \circ T(\underline{X})` which is the polynomial chaos approximation as a Function. We have :math:`\displaystyle \hat{g} = \sum_{k \in K} \underline{\alpha}_k \Psi_k \circ T`,
# - the truncated multivariate basis : :math:`(\Psi_k)_{k \in K}`,
# - the indices :math:`K`,
# - the composition of each polynomial of the truncated multivariate basis :math:`\Psi_k`,
# - the distribution :math:`\mu` of the transformed variables :math:`\underline{Z}`,
#

# %%
from __future__ import print_function
import openturns as ot
import openturns.viewer as viewer
from matplotlib import pylab as plt
ot.Log.Show(ot.Log.NONE)

# %%
# prepare some X/Y data
ot.RandomGenerator.SetSeed(0)
dimension = 2
input_names = ['x1', 'x2']
formulas = ['cos(x1 + x2)', '(x2 + 1) * exp(x1 - 2 * x2)']
model = ot.SymbolicFunction(input_names, formulas)
distribution = ot.Normal(dimension)
x  = distribution.getSample(30)
y = model(x)

# %%
# create a functional chaos algorithm
algo = ot.FunctionalChaosAlgorithm(x, y)
algo.run()

# %%
# Stream out the result
result = algo.getResult()

# %%
# Get the polynomial chaos coefficients
# All the coefficients
result.getCoefficients()

# %%
# The coefficients of marginal i
i = 1
result.getCoefficients()[i]

# %%
# Get the indices of the selected polynomials : K
subsetK = result.getIndices()
subsetK

# %%
# Get the composition of the polynomials
# of the truncated multivariate basis
for i in range(subsetK.getSize()):
    print("Polynomial number ", i, " in truncated basis <-> polynomial number ",
          subsetK[i], " = ", ot.LinearEnumerateFunction(dimension)(subsetK[i]), " in complete basis")

# %%
# Get the multivariate basis
# as a collection of Function
reduced = result.getReducedBasis()

# %%
# Get the orthogonal basis
orthgBasis = result.getOrthogonalBasis()
orthgBasis

# %%
# Get the distribution of variables Z
orthgBasis.getMeasure()

# %%
# Get the composed model which is the model of the reduced variables Z
result.getComposedModel()

# %%
# Get the composed meta model which is the model of the reduced variables Z
# within the reduced polynomials basis
result.getComposedMetaModel()

# %%
# Get the meta model which is the composed meta model combined with the
# iso probabilistic transformation
result.getMetaModel()

# %%
# Get the projection strategy
algo.getProjectionStrategy()
